<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\BaseController;
use App\Repositories\AccountRepository;
use Illuminate\Http\Request;    //引用http请求类
use App\Exceptions\BasicException;  //引入框架异常处理类
use Illuminate\Support\Facades\Hash;    //引入hash
use App\Services\Tools\JwtService;    //引入JWT服务
use App\Services\Tools\FileService;   //引入文件处理类
use App\Response\Response;
use Illuminate\Support\Facades\Storage;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use App\Services\Tools\ExportService;   //引入导出服务
use Illuminate\Support\Facades\DB;  //引用DB

class TestController extends BaseController
{
    protected $invalidChars;

    public function __construct()
    {
        $punctuations = [',', '，', ' '];
        $chars = ['必传', '必须', '非必传', '非必须', '可选'];
        $this->invalidChars = [];
        foreach ($punctuations as $punctuation) {
            foreach ($chars as $char) {
                $this->invalidChars[] = $punctuation . $char;
            }
        }
    }

    /**
     * 导出短信需要的数据
     * @param Request $request
     * @return string
     * @throws BasicException
     */
    public function smsExport(Request $request)
    {
        set_time_limit(0);

//        $final_data = [];
//        for($i =1; $i < 8; $i++)
//        {
//            $list = app('model_user_recharge')->with(['user'=>function($query) {
//
//                $query->select('user_id','mobile');
//
//            }])->where('status',2)->select('id','user_id',DB::raw('sum(money) as total_money'))->groupBy('user_id')->paginate(10000, ['*'], '', $i);
//
//            $data = [];
//            foreach($list as &$val)
//            {
//                if(isset($val->user->mobile) && !empty($val->user->mobile))
//                {
//                    if($val->total_money <= 500)
//                    {
//
//                        $data[] = [
//                            'mobile' => $val->user->mobile,
//                            'name' => '气泡客户',
//                            'sex' => '女',
//                            'age' => 18,
//                            'birth' => '2020-07-28',
//                            'amount' => $val->total_money,
//                            'user_id' => $val->user_id
//                        ];
//                    }
//                }
//
//            }
//
//            $final_data = array_merge($final_data,$data);
//        }


        $final_data = [];
        for($i =1; $i< 12; $i++)
        {
            $list = app('model_user')->with(['user_data'=>function($query) {
                $query->select('user_id','sex');
            }])->where('disabled',1)->where('deleted',0)->select('user_id','mobile')->paginate(10000, ['*'], '', $i);

            $data = [];
            //循环遍历数据
            foreach($list as &$val)
            {
                if(isset($val->mobile) && !empty($val->mobile))
                {

                    if(isset($val->user_data->sex) && !empty($val->user_data->sex) && ($val->user_data->sex == 1)) {

                        $data[] = [
                            'mobile' => $val->mobile,
                            'name' => '冰语客户',
                            'sex' => '男',
                            'age' => 18,
                            'birth' => '2020-07-28',
                            'gender' => $val->user_data->sex,
                            'user_id' => $val->user_id
                        ];
                    }

                }
            }

            $final_data = array_merge($final_data,$data);
        }


        $headings = [
            '手机号码',
            '姓名',
            '性别',
            '年龄',
            '出生年月',
            '性别标志',
            '用户编号'
        ];
        $filename = '/sociaty_excel/'.date('YmdHis').mt_rand(100,999).'男性用户.xlsx';
        $res = app('excel')->store(new ExportService($final_data,$headings),$filename,'oss','Xlsx');
        if(!$res) throw new BasicException(90030);
        return 'http://'.env('OSS_BUCKET').'.'.env('OSS_ENDPOINT').$filename;



    }

    //获取所有系统路由
    public function getAllRouteInfo()
    {
        $subMenus = [
            ['id' => 3, 'name' => '管理员列表', 'parent_id' => 1],
            ['id' => 4, 'name' => '角色列表', 'parent_id' => 1],
            ['id' => 5, 'name' => '用户列表', 'parent_id' => 2],
            ['id' => 6, 'name' => '设备封禁列表', 'parent_id' => 2],
        ];

        $menus = [
            ['id' => 1, 'name' => '系统管理'],
            ['id' => 2, 'name' => '用户管理'],
        ];


        foreach ($menus as &$menu) {
            foreach ($subMenus as $subMenu) {
                if ($subMenu['parent_id'] == $menu['id']) {
                    $menu['children'][] = $subMenu;
                }
            }
        }

        dd($menus);
        //指定要获取哪些中间件下面的路由，多个中间件的话将返回同时包含的
        $targetMiddlewares = ['cors'];

        //读取路由文件，转为数组
        $file = base_path('routes/') . 'web.php';
        $content = file_get_contents($file);
        $content = str_replace(' ', '', $content);
        $arr = explode("\n", $content);

        $validKeywords = ['group', 'get', 'post', 'put', 'delete', 'addRoute', '}', ')', 'return'];
        foreach ($arr as $k => $v) {
            $flag = 0;
            foreach ($validKeywords as $validKeyword) {
                if (strpos($v, $validKeyword) !== false) {
                    $flag = 1;
                    break;
                }
            }
            if ($flag == 0) unset($arr[$k]);
        }
        $arr = array_values($arr);

        //保存所有格式化后的路由
        $formatRoutes = [];
        //有效的请求方式
        $methods = ['get', 'post', 'put', 'delete'];
        //保存路由组的前缀
        $groupPrefix = [];
        //保存路由组的中间件
        $groupMiddleware = [];
        echo '<pre>';

        foreach ($arr as $v) {

            //忽略被注释的行
            if (isset($v[0]) && $v[0] == '/' && isset($v[1]) && $v[1] == '/') continue;

            //解析路由组的前缀，中间件等信息
            if (strpos($v, '->group') !== false) {
                $groupInfo = $this->analysisGroupConfig($v);
                $groupPrefix[] = $groupInfo['prefix'];
                $groupMiddleware[] = $groupInfo['middleware'];
            }

            //每遇到一个}减掉一层路由前缀和中间件
            if (strpos($v, '})') !== false) {
                $charCount = substr_count($v, '})');
                for ($i = 0; $i < $charCount; $i++) {
                    array_pop($groupPrefix);
                    array_pop($groupMiddleware);
                }
            }

            //解析路由信息
            foreach ($methods as $method) {
                if (strpos($v, '->' . $method) !== false) {
                    //解析路由
                    $routeInfo = $this->analysisRoute1($v);
                    //拼接路由组的公共前缀
                    $routeInfo = $this->jointPrefix($groupPrefix, $routeInfo);
                    //追加中间件字段
                    $routeInfo = $this->appendMiddleware($groupMiddleware, $routeInfo);
                    $flag = 1;
                    foreach ($targetMiddlewares as $targetMiddleware) {
                        if (!in_array($targetMiddleware, $routeInfo['middleware'])) {
                            $flag = 0;break;
                        }
                    }
                    if ($flag == 1) {
                        $formatRoutes[] = $routeInfo;
                    }
                }
            }

            if (strpos($v, '->addRoute') !== false) {
                $routeInfo = $this->analysisRoute2($v);
                $routeInfo = $this->jointPrefix($groupPrefix, $routeInfo);
                $routeInfo = $this->appendMiddleware($groupMiddleware, $routeInfo);
                $flag = 1;
                foreach ($targetMiddlewares as $targetMiddleware) {
                    if (!in_array($targetMiddleware, $routeInfo['middleware'])) {
                        $flag = 0;break;
                    }
                }
                if ($flag == 1) {
                    $formatRoutes[] = $routeInfo;
                }
            }
        }

        $giftRoutes = '';
        foreach ($formatRoutes as $formatRoute) {
            $tmp = substr($formatRoute['uri'], 0, 6);
            if ($tmp == '/gift/') {
                $giftRoutes .= $formatRoute['name'] . ' ' . $formatRoute['uri'] . ' ' . $formatRoute['method'];
            }
        }
        dd($giftRoutes);
    }

    //解析路由组配置
    private function analysisGroupConfig($content = '')
    {
//        $content = "router->group(['prefix'=>'OpenApi','namespace'=>'Admin','middleware'=>['cors']],function(app){";
//        $content = "uter->group(['namespace' => 'Admin', 'middleware' => 'api'], function";
        //去掉最外层的中括号[]
        $startIndex = strpos($content, '[');
        $endIndex = strrpos($content, ']');
        $content = substr($content, $startIndex + 1, $endIndex - $startIndex - 1);
        if (empty($content)) {
            return ['prefix' => '', 'middleware' => []];
        }

        //解析[]里面加载的中间件
        $startIndex = strpos($content, '[');
        $endIndex = strrpos($content, ']');
        if ($startIndex !== false) {
            $middlewareStr = substr($content, $startIndex + 1, $endIndex - $startIndex - 1);
            $middlewareStr = $this->rmInvalidChar($middlewareStr);
            $middleware = explode(',', $middlewareStr);
            $content = substr($content, 0, $startIndex) . substr($content, $endIndex + 1);
        } else {
            $middleware = [];
        }

        $content = $this->rmInvalidChar($content);
        $arr = explode(',', $content);
        $groupInfo = [];
        foreach ($arr as $v) {
            if ($v) {
                $v = explode('=>', $v);
                $groupInfo[$v[0]] = $v[1];
            }
        }

        $groupInfo['prefix'] = isset($groupInfo['prefix']) ? trim($groupInfo['prefix'], '/') : '';

        if (isset($groupInfo['middleware']) && empty($middleware)) {
            $groupInfo['middleware'] = [$groupInfo['middleware']];
        } else {
            $groupInfo['middleware'] = $middleware;
        }

        return $groupInfo;
    }

    private function analysisRoute1($content = '')
    {
//        $content = "->get('permission/getRoutes', 'PermissionController@getRoutes'); //获取所有路由";
        $startIndex = strpos($content, '>');
        $endIndex = strpos($content, '(');
        $method = substr($content, $startIndex + 1, $endIndex - $startIndex - 1);
        $method = $this->rmInvalidChar($method);

        $content = substr($content, $endIndex);
        $content = $this->rmInvalidChar($content);
        $arr = explode(',', $content);
        $uri = trim($arr[0], '/');
        $content = $arr[1];
        $arr = explode('//', $content);
        $name = trim($arr[1] ?? '');

        return [
            'name' => $name,
            'uri' => $uri,
            'method' => $method
        ];
    }

    private function analysisRoute2($content = '')
    {
//        $content = "->addRoute(['OPTIONS','POST'] , '/menu/add','PermissionController@menuAdd'); //添加菜单";
        $startIndex = strpos($content, '[');
        $endIndex = strpos($content, ']');
        $methods = substr($content, $startIndex + 1, $endIndex - $startIndex - 1);
        $methods = strtolower($methods);
        $methods = $this->rmInvalidChar($methods);
        $methods = explode(',', $methods);
        $validMethods = ['get', 'post', 'put', 'delete'];
        foreach ($methods as $method) {
            if (in_array($method, $validMethods)) {
                break;
            }
        }

        $content = substr($content, $endIndex + 1);
        $content = trim($content);
        $content = trim($content, ',');
        $arr = explode(',', $content);
        $arr = array_filter($arr);
        $arr = array_values($arr);
        $uri = $this->rmInvalidChar($arr[0]);
        $uri = trim($uri, '/');
        $arr = explode('//', $arr[1]);
        $name = trim($arr[1] ?? '');

        return [
            'name' => $name,
            'uri' => $uri,
            'method' => $method
        ];
    }

    //拼接路由组的前缀
    private function jointPrefix($groupPrefix, $routeInfo)
    {
        $prefixStr = '';
        foreach ($groupPrefix as $prefix) {
            if ($prefix) {
                $prefixStr .= '/' . $prefix;
            }
        }
        $routeInfo['uri'] = $prefixStr . '/' . $routeInfo['uri'];
        $routeInfo['uri'] = rtrim($routeInfo['uri'], '/');
        return $routeInfo;
    }

    //为路由追加中间件
    private function appendMiddleware($groupMiddleware, $routeInfo)
    {
        $routeMiddleware = [];
        foreach ($groupMiddleware as $middleware) {
            if ($middleware) {
                $routeMiddleware = array_merge($routeMiddleware, $middleware);
            }
        }
        $routeInfo['middleware'] = $routeMiddleware;
        return $routeInfo;
    }

    //去掉无效的字符
    private function rmInvalidChar($content)
    {
        $invalidChar = ['\'', '"', ' ', ';', '(', ')', '[', ']'];
        foreach ($invalidChar as $char) {
            $content = str_replace($char, '', $content);
        }
        return $content;
    }

    //获取所有接口参数
    public function getAllApiInfo()
    {
        $dir = base_path('app/Http/Controllers/Admin');
        $dir = str_replace('\\', '/', $dir);
        $apiInfo = $this->getApiInfo($dir);
        dd($apiInfo);
    }

    //获取所有接口信息
    private function getApiInfo($dir)
    {
        echo '<pre>';
        //保存接口信息
        static $apiInfo = [];

        //打开目录
        $dirHandle = opendir($dir);

        while (($filename = readdir($dirHandle)) !== false) {

            if ($filename == '.' || $filename == '..') continue;

            $file = $dir . '/' . $filename;

            if (is_dir($file)) {
                $this->getApiInfo($file);
            } else if (is_file($file)) {
                $this->readFile($file, $apiInfo);
            } else {
                closedir($dirHandle);
                die($file);
            }
        }

        //关闭目录
        closedir($dirHandle);

        return $apiInfo;
    }

    private function readFile($file, &$apiInfo)
    {
        //获取文件数据
        $rows = file_get_contents($file);
        $rows = explode("\n", $rows);

        foreach ($rows as $row) {

            $row = trim($row);
            if (substr($row, 0, 1) != '*') continue;

            //获取接口名称
            if (strpos($row, '@api ') !== false) {
                $tmp = explode(' ', $row);
                $apiName = $tmp[count($tmp) - 1];
            }

            //获取接口所有参数
            if (strpos($row, 'apiParam') !== false) {

                $param = substr($row, strpos($row, '}') + 1);
                $param = trim($param);
                $firstSpaceIndex = strpos($param, ' ');
                $fieldKey = substr($param, 0, $firstSpaceIndex);
                $fieldName = substr($param, $firstSpaceIndex);
                foreach ($this->invalidChars as $invalidChar) {
                    $fieldName = str_replace($invalidChar, '', $fieldName);
                }
                $fieldName = trim($fieldName);
                $fieldName = trim($fieldName, ',');
                $fieldName = trim($fieldName, '，');
                $fieldName = strtolower($fieldName);

                if (isset($apiInfo[$fieldKey])) {
                    if (!in_array($fieldName, $apiInfo[$fieldKey]['field_name'])) {
                        $apiInfo[$fieldKey]['field_name'][] = $fieldName;
                    }
                    $apiInfo[$fieldKey]['api_name'] .= " | {$apiName}";
                } else {
                    $apiInfo[$fieldKey]['field_name'][] = $fieldName;
                    $apiInfo[$fieldKey]['api_name'] = $apiName;
                }
            }
        }
    }

    //生成图片
    public function createImg($chars = 666, $adminId = 123)
    {
        $chars = (string)$chars;
        $charsLen = strlen($chars);

        $imgWidth = 108;
        $imgHeight = 108;

        //创建图片资源
        $im = imagecreate($imgWidth,$imgHeight);

        //设置并填充图片背景颜色
        $backgroundColor = imagecolorallocatealpha($im,0,0,0, 127); //透明度0-127，127表示完全透明
        imagefill($im,0, 0, $backgroundColor); //x=0，y=0代表从左上角开始填充

        //填充字符
        $charColor = imagecolorallocate($im,255,227,190);
        $charInterval = 8; //字符间隔
        $x = ($imgWidth - $charsLen * $charInterval) / 2;
        imagestring($im, 5, $x, 42, $chars, $charColor);

        //设置文件名和本地保存路径
        $filename = time() . $adminId . str_random(4) . '.png';
        $file = storage_path('app/') . $filename;
        imagepng($im, $file);
        dd('ok');
    }

    //账单测试
    public function accountTest(){

        /**@var AccountRepository $accountRepo*/
        $accountRepo=app("repo_account");
//        $accountRepo->change(1, 29, 1, 4, 5, 6);

        var_dump(1);die();
    }
}
